package process.service;

import java.util.List;

import javax.annotation.PostConstruct;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import process.model.OntoResource;
import process.module.OntoQuery;

import com.hp.hpl.jena.ontology.OntClass;
import com.hp.hpl.jena.ontology.OntModel;
import com.hp.hpl.jena.ontology.OntModelSpec;
import com.hp.hpl.jena.rdf.model.ModelFactory;
import com.hp.hpl.jena.util.FileManager;
import com.hp.hpl.jena.util.iterator.ExtendedIterator;

import core.constant.SystemConstant;
import domain.web.dao.CategoryDao;
import domain.web.dao.ManufacturerDao;
import domain.web.dao.ProductDao;
import domain.web.model.Category;
import domain.web.model.Manufacturer;
import domain.web.model.Product;

@Service
public class DbBuilderService {

	@Autowired
	CategoryDao categoryDao;
	@Autowired
	ProductDao productDao;
	@Autowired
	ManufacturerDao manufacturerDao;

	private OntoQuery ontoQuery;
	private OntModel m;

	@PostConstruct
	public void initialize() {
		ontoQuery = new OntoQuery();
		m = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM);
		FileManager.get().readModel(m, SystemConstant.O_FILE);
	}

	public DbBuilderService() {
		ontoQuery = new OntoQuery();
		m = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM);
		FileManager.get().readModel(m, SystemConstant.O_FILE);
	}

	public void buildManufacturer() {
		List<OntoResource> ms = ontoQuery.getInstanceFromClass("Manufacturer");
		for (OntoResource ontoResource : ms) {
			Manufacturer manufacturer = new Manufacturer(0, OntoQuery
					.getClearName(ontoResource.getName()).trim(), OntoQuery
					.getNameFromUri(ontoResource.getUri()).trim(), "");
			manufacturerDao.insert(manufacturer);
			System.out.println(manufacturer.getName() + " inserted");
		}
	}

	public void buildTopCategory() {
		// List<OntoResource> list = new ArrayList<OntoResource>();
		ExtendedIterator<OntClass> iter = m.listHierarchyRootClasses();
		while (iter.hasNext()) {
			OntClass ontClass = (OntClass) iter.next();
			if (ontClass.getLocalName().equalsIgnoreCase("Manufacturer")) {
				// do nothing
			} else {
				System.out.println(ontClass.getLocalName() + " - "
						+ ontClass.getURI());
				Category category = new Category(0,
						OntoQuery.getClearName(ontClass.getLocalName()), 0,
						OntoQuery.getNameFromUri(ontClass.getURI()));
				category.setName_vi(category.getName());
				long id = categoryDao.insert(category);
				System.out.println(category.getName() + " inserted");
				recursiveThroughOntologyToGetClass(ontClass, id);
			}
		}
	}

	private void recursiveThroughOntologyToGetClass(OntClass node, long parentId) {
		if (node.hasSubClass()) {
			ExtendedIterator<OntClass> iter = node.listSubClasses(true);
			while (iter.hasNext()) {
				OntClass hierarchy = iter.next();
				System.out.println("\t" + hierarchy.getLocalName() + " - "
						+ hierarchy.getURI());
				// insert
				Category category = new Category(0,
						OntoQuery.getClearName(hierarchy.getLocalName()),
						parentId, OntoQuery.getNameFromUri(hierarchy.getURI()));
				category.setName_vi(category.getName());
				long id = categoryDao.insert(category);
				System.out.println(category.getName() + " inserted");
				recursiveThroughOntologyToGetClass(hierarchy, id);
			}
		} else {
			buildProduct(parentId, node.getLocalName());
		}
	}

	public void buildProduct(long catId, String menu) {
		List<OntoResource> products = ontoQuery.getInstanceFromClass(menu);
		for (OntoResource ontoResource : products) {
			Product productCheck = productDao.get(OntoQuery
					.getNameFromUri(ontoResource.getUri()));
			if (productCheck != null) {
				System.out.println(ontoResource.getName() + " ALREADY HAVE!!!");
				continue;
			}

			try {
				// String manufacturer = OntoQuery.getNameFromUri(ontoResource
				// .getUri());
				// manufacturer = OntoQuery.getClearName(manufacturer);
				// manufacturer = manufacturer.split(" ")[0];
				String manufacturer = ontoQuery.getManufacturer(OntoQuery
						.getNameFromUri(ontoResource.getUri()));
				System.out.println(manufacturer);
				long m = manufacturerDao.getByUri(manufacturer).getId();

				Product product = new Product();
				product.setCategoryId(catId);
				product.setManufacturerId(m);
				product.setName(OntoQuery.getClearName(ontoResource.getName()));
				product.setUri(OntoQuery.getNameFromUri(ontoResource.getUri()));

				productDao.insert(product);
				System.out.println("Product: " + product.getName()
						+ " inserted");
			} catch (Exception ex) {
				// System.out.println(ontoResource.getName() + " Failed");
				ex.printStackTrace();
			}
		}
	}

	public void updateProduct() {
		List<Category> tops = categoryDao.getTopList("vi");
		for (Category top : tops) {
			List<Category> subs = categoryDao.getSubList(top.getId(), "vi");
			for (Category sub : subs) {
				buildProduct(sub.getId(), sub.getUri());
			}
		}
	}

	public static void main(String[] args) {
		DbBuilderService b = new DbBuilderService();
		b.buildTopCategory();
	}

}